<template>
  <div>
    <div class="header-action">
      <el-button type="primary" class="clear-color" plain @click="handleAllSelect">全选</el-button>
    </div>
    <div class="hole">
      <div class="holesTable">
        <table cellspacing="0" border-collapse="0" id="box">
          <thead>
            <template v-for="(item, index) in tableData">
              <tr align="center" v-if="index === 0" :key="index">
                <td class="label" style="max-width: 60px;"></td>
                <td v-for="head in 12" :key="head" class="label">
                  {{ head }}
                </td>
              </tr>
            </template>
          </thead>
          <tr align="center" v-for="(item, i) in tableData" :key="i">
            <template v-if="item.row">
              <td class="label" style="max-width: 60px;">{{ item.row }}</td>
              <td
                :class="(fillInHole.includes(`${item.row}${i + 1}`)) ? 'item' : 'noItem'" 
                :style="{ 'background-color': item.content[i + 1] || '' }"
                :data-hole="`${item.row}${i + 1}`"
                :data-index="i+1"
                v-for="(head, i) in 12" 
                :key="head">
                <el-input
                  :disabled="!(fillInHole.includes(`${item.row}${i + 1}`))"
                  :placeholder="`${item.row}${i + 1}`" 
                  v-model="item.value[`${item.row}${i + 1}`]" 
                  class="holeValue" />
              </td>
              <div v-if="i === 0" class="mask"></div>
            </template>
          </tr>
        </table>
      </div>
    </div>
  </div>
</template>
<script>
import { COLORS } from './constants'
export default {
  props: {
    fillInHole: {
      type: Array,
      default: () => []
    },
    // 回显96孔的数据
    echoHolesValues: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      tableData: [
        {
          row: "A",
          content: {},
          value: { },
        },
        {
          row: "B",
          content: {},
          value: {},
        },
        {
          row: "C",
          content: {},
          value: {},
        },
        {
          row: "D",
          content: {},
          value: {},
        },
        {
          row: "E",
          content: {},
          value: {},
        },
        {
          row: "F",
          content: {},
          value: {},
        },
        {
          row: "G",
          content: {},
          value: {},
        },
        {
          row: "H",
          content: {},
          value: {},
        },
      ],
      selectList: [],
      color: '#ff4500',
      predefineColors: COLORS
    };
  },
  watch: {
    tableData: {
      handler(newVal) {
        this.$emit('handleSetVal', newVal)
      },
      deep: true  // 深度监听
    },
    echoHolesValues: {
      handler(newVal) {
        if(!newVal || !newVal.crpValue) return
        newVal.crpValue.forEach(item => {
          this.tableData.forEach(holeItem => {
            if(item.slice(0, 1) === holeItem.row) {
              const [hole, val] = item.split(':')
              holeItem.value[hole] = val
            }
          })
        })

        if(!newVal.wtsonDtoList) return
        newVal.wtsonDtoList.forEach(item => {
          this.tableData.forEach(holeItem => {
            const holes = item.label.split('&')
            for (let i = 0; i < holes.length; i++) {
              const chole = holes[i];
              if(chole[0] === holeItem.row) {
                holeItem.content[chole[1]] = item.color
              }
            }
          })
        })

        setTimeout(() => {
          this.$emit('handleSetVal', this.tableData)
          this.$emit('handleEnd', this.tableData)
        }, 500);
      },
      deep: true,
      immediate: true
    }
  },
  mounted() {
    const _this = this
    const parent = document.getElementById("box");
    const mask = document.querySelector(".mask");

    // 选中的元素
    let selectList = [];

    // 遮罩层的四角位置
    let startTop = 0,
      endTop = 0,
      startLeft = 0,
      endLeft = 0;

    let isDelete = false
    
    // 鼠标点击触发
    parent.onmousedown = function(e) {
      if (e.button !== 0) return;
          
      parent.addEventListener('keydown', handleDeleted)
      // 只有鼠标左键可以触发遮罩层
      parent.addEventListener("mousemove", getMousePosition);
      startTop = e.y - parent.getBoundingClientRect().top;
      startLeft = e.x - parent.getBoundingClientRect().left;
      // startTop = e.y - parent.offsetTop;
      // startLeft = e.x - parent.offsetLeft;
    };

    // 关闭 F12 菜单
    // document.addEventListener('contextmenu',function(e){
    //   e.preventDefault();
    // })

    // 鼠标移动超出 元素宽高，则重置 信息
    parent.addEventListener("mouseleave", function() {
      resetPosition();
    });

    // 鼠标抬起触发
    parent.onmouseup = (e) => {
      if (e.button !== 0) return;
      if(mask.clientHeight < 10 && mask.clientWidth < 10) return resetPosition();
      _this.selectList.forEach(hole => {
        _this.tableData.forEach(item => {
          if(item.row === hole[0]) {
            if(isDelete) {
              delete item.content[hole.slice(1)]
            } else {
              item.content[hole.slice(1)] = _this.color
            }
          }
        })
      })
      _this.$forceUpdate()

      this.$emit('handleEnd', this.tableData)

      // _this.handleAllValue()

      resetPosition();
    };

    // 是否为删除
    function handleDeleted(e) {
      if(e.keyCode === 17) {
        isDelete = true
      }
    }
    
    // 计算下一个选中的颜色
    function setNextColor() {
      let allColor = []
      const colorList = _this.tableData.map(item => Object.values(item.content))
      colorList.map(item => allColor.push(...item))
      allColor =  Array.from(new Set(allColor))
      _this.predefineColors.map(item => {
        if(!allColor.includes(item)) {
          _this.color = item
        }
      })
    }

    // 重置鼠标选中信息
    function resetPosition() {
      parent.removeEventListener("mousemove", getMousePosition);
      parent.removeEventListener('keydown', handleDeleted)
      isDelete = false
      mask.style.width = 0 + "px";
      mask.style.height = 0 + "px";
      startTop = 0, 
      endTop = 0, 
      startLeft = 0, 
      endLeft = 0;
    }

    // 鼠标移动触发
    function getMousePosition() {
      // 获取大盒子下的所有可选中的子元素
      const childrenList = parent.querySelectorAll(".item");
      // 获取遮罩层位置信息
      const maskPosition = mask.getBoundingClientRect();
      // 鼠标移动触发时，先清空数据
      selectList = [];

      for (let i = 0; i < childrenList.length; i++) {
        // 获取每个子元素的位置信息
        const { left, top, right, bottom } = childrenList[
          i
        ].getBoundingClientRect();
        if (
          right > maskPosition.left &&
          bottom > maskPosition.top &&
          left < maskPosition.right &&
          top < maskPosition.bottom
        ) {

          // 如果拖拽的遮罩的宽高都小于10，那么判定为不操作选中
          if(mask.clientHeight > 10 && mask.clientWidth > 10) {
            // 获取选中的子元素索引
            selectList.push(childrenList[i].dataset.hole);
            _this.selectList = selectList
          }
        }
      }
      // 获取移动中的鼠标位置
      // endTop = window.event.y - parent.offsetTop;
      // endLeft = window.event.x - parent.offsetLeft;
      endTop = window.event.y - parent.getBoundingClientRect().top;
      endLeft = window.event.x - parent.getBoundingClientRect().left;
      // 设置遮罩层的位置
      mask.style.top = Math.min(startTop, endTop) + "px";
      mask.style.left = Math.min(startLeft, endLeft) + "px";

      // 计算遮罩层宽高
      const maskWidth = Math.abs(startLeft - endLeft);
      const maskHeight = Math.abs(startTop - endTop);
      mask.style.width = maskWidth + "px";
      mask.style.height = maskHeight + "px";

      // 计算下一次拖拽的颜色
      setNextColor()
    }
  },
  methods: {
    // 全选按钮
    handleAllSelect() {
      this.fillInHole.forEach(hole => {
        this.tableData.forEach(item => {
          if(item.row === hole[0]) {
            item.content[hole.slice(1)] = '#4d4499'
          }
        })
      })
      this.$forceUpdate()

      this.$emit('handleEnd', this.tableData)
    },
    handleClear() {
      this.tableData = this.tableData.map(item => {
        return {
          ...item,
          content: {},
          value: {}
        }
      })
    }
  }
};
</script>
<style lang="scss" scoped>
.hole {
  width: 100%;
  height: 100%;
  .holesTable {
  width: 100%;
  #box {
    width: 100%;
    height: 100%;
    margin: 0 auto;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    position: relative;
    z-index: 999;
    .item {
      height: 100%;
      background-color: rgb(160, 202, 239);
    }
    .noItem {
      height: 100%;
      background-color: rgb(160, 202, 239);
    }
  }
  table {
    border-width: 0.1px;
    border-color: #b9cede;
    thead {
      width: 100%;
    }
    tr {
      display: flex;
      align-items: center;
      height: 100%;
      // background-color: #409eff;
      .label {
        flex: 1;
        background-color: #409eff;
        color: #fff;
        box-sizing: border-box;
      }
      td {
        flex: 1;
        min-height: 50px;
        box-sizing: border-box;
        border-color: #b9cede;
        border: 1px solid #b9cede;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0 6px;
        ::v-deep {
          .el-input__inner {
            padding: 0 5px;
          }
        }
      }
    }
  }
  .active {
    background-color: #dbf3ff;
    height: 40px;
    line-height: 40px;
    cursor: not-allowed;
  }
  .computed {
    background-color: #89afe0;
    height: 40px;
    line-height: 40px;
  }
}
}
::v-deep {
  .el-input.is-disabled .el-input__inner {
    background-color: #c0c4cc;
    cursor: default;
  }
}
.header-action {
  display: flex;
  align-items: center;
  .clear-color {
    margin: 20px 0;
  }
}
.mask {
  position: absolute;
  z-index: 999;
  width: 0px;
  height: 0px;
  background-color: #000;
  opacity: 0.4;
}
</style>
